diff --git a/cmd/dex/config.go b/cmd/dex/config.go
index 88dc98e7..3c274743 100644
--- a/cmd/dex/config.go
+++ b/cmd/dex/config.go
@@ -86,11 +86,12 @@ type password storage.Password
 
 func (p *password) UnmarshalJSON(b []byte) error {
 	var data struct {
-		Email       string `json:"email"`
-		Username    string `json:"username"`
-		UserID      string `json:"userID"`
-		Hash        string `json:"hash"`
-		HashFromEnv string `json:"hashFromEnv"`
+		Email       string   `json:"email"`
+		Username    string   `json:"username"`
+		UserID      string   `json:"userID"`
+		Hash        string   `json:"hash"`
+		HashFromEnv string   `json:"hashFromEnv"`
+		Groups      []string `json:"groups"`
 	}
 	if err := json.Unmarshal(b, &data); err != nil {
 		return err
@@ -99,6 +100,7 @@ func (p *password) UnmarshalJSON(b []byte) error {
 		Email:    data.Email,
 		Username: data.Username,
 		UserID:   data.UserID,
+		Groups:   data.Groups,
 	})
 	if len(data.Hash) == 0 && len(data.HashFromEnv) > 0 {
 		data.Hash = os.Getenv(data.HashFromEnv)
diff --git a/server/server.go b/server/server.go
index a79b7cfd..b21c7847 100644
--- a/server/server.go
+++ b/server/server.go
@@ -382,6 +382,7 @@ type passwordDB struct {
 }
 
 func (db passwordDB) Login(ctx context.Context, s connector.Scopes, email, password string) (connector.Identity, bool, error) {
+
 	p, err := db.s.GetPassword(email)
 	if err != nil {
 		if err != storage.ErrNotFound {
@@ -397,11 +398,13 @@ func (db passwordDB) Login(ctx context.Context, s connector.Scopes, email, passw
 	if err := bcrypt.CompareHashAndPassword(p.Hash, []byte(password)); err != nil {
 		return connector.Identity{}, false, nil
 	}
+
 	return connector.Identity{
 		UserID:        p.UserID,
 		Username:      p.Username,
 		Email:         p.Email,
 		EmailVerified: true,
+		Groups:        p.Groups,
 	}, true, nil
 }
 
diff --git a/storage/kubernetes/types.go b/storage/kubernetes/types.go
index 07e25084..05608b6f 100644
--- a/storage/kubernetes/types.go
+++ b/storage/kubernetes/types.go
@@ -373,9 +373,10 @@ type Password struct {
 	// This field is IMMUTABLE. Do not change.
 	Email string `json:"email,omitempty"`
 
-	Hash     []byte `json:"hash,omitempty"`
-	Username string `json:"username,omitempty"`
-	UserID   string `json:"userID,omitempty"`
+	Hash     []byte   `json:"hash,omitempty"`
+	Username string   `json:"username,omitempty"`
+	UserID   string   `json:"userID,omitempty"`
+	Groups   []string `json:"groups,omitempty"`
 }
 
 // PasswordList is a list of Passwords.
@@ -400,6 +401,7 @@ func (cli *client) fromStoragePassword(p storage.Password) Password {
 		Hash:     p.Hash,
 		Username: p.Username,
 		UserID:   p.UserID,
+		Groups:   p.Groups,
 	}
 }
 
@@ -409,6 +411,7 @@ func toStoragePassword(p Password) storage.Password {
 		Hash:     p.Hash,
 		Username: p.Username,
 		UserID:   p.UserID,
+		Groups:   p.Groups,
 	}
 }
 
diff --git a/storage/sql/crud.go b/storage/sql/crud.go
index 4451e5c5..e2ef588d 100644
--- a/storage/sql/crud.go
+++ b/storage/sql/crud.go
@@ -592,13 +592,13 @@ func (c *conn) CreatePassword(p storage.Password) error {
 	p.Email = strings.ToLower(p.Email)
 	_, err := c.Exec(`
 		insert into password (
-			email, hash, username, user_id
+			email, hash, username, user_id, groups
 		)
 		values (
-			$1, $2, $3, $4
+			$1, $2, $3, $4, $5
 		);
 	`,
-		p.Email, p.Hash, p.Username, p.UserID,
+		p.Email, p.Hash, p.Username, p.UserID, encoder(p.Groups),
 	)
 	if err != nil {
 		if c.alreadyExistsCheck(err) {
@@ -623,10 +623,10 @@ func (c *conn) UpdatePassword(email string, updater func(p storage.Password) (st
 		_, err = tx.Exec(`
 			update password
 			set
-				hash = $1, username = $2, user_id = $3
-			where email = $4;
+				hash = $1, username = $2, user_id = $3, groups = $4
+			where email = $5;
 		`,
-			np.Hash, np.Username, np.UserID, p.Email,
+			np.Hash, np.Username, np.UserID, encoder(p.Groups), p.Email,
 		)
 		if err != nil {
 			return fmt.Errorf("update password: %v", err)
@@ -642,7 +642,7 @@ func (c *conn) GetPassword(email string) (storage.Password, error) {
 func getPassword(q querier, email string) (p storage.Password, err error) {
 	return scanPassword(q.QueryRow(`
 		select
-			email, hash, username, user_id
+			email, hash, username, user_id, groups
 		from password where email = $1;
 	`, strings.ToLower(email)))
 }
@@ -650,7 +650,7 @@ func getPassword(q querier, email string) (p storage.Password, err error) {
 func (c *conn) ListPasswords() ([]storage.Password, error) {
 	rows, err := c.Query(`
 		select
-			email, hash, username, user_id
+			email, hash, username, user_id, groups
 		from password;
 	`)
 	if err != nil {
@@ -674,7 +674,7 @@ func (c *conn) ListPasswords() ([]storage.Password, error) {
 
 func scanPassword(s scanner) (p storage.Password, err error) {
 	err = s.Scan(
-		&p.Email, &p.Hash, &p.Username, &p.UserID,
+		&p.Email, &p.Hash, &p.Username, &p.UserID, decoder(&p.Groups),
 	)
 	if err != nil {
 		if err == sql.ErrNoRows {
diff --git a/storage/storage.go b/storage/storage.go
index c308ac46..424ef087 100644
--- a/storage/storage.go
+++ b/storage/storage.go
@@ -343,6 +343,9 @@ type Password struct {
 
 	// Randomly generated user ID. This is NOT the primary ID of the Password object.
 	UserID string `json:"userID"`
+
+	// Groups assigned to the user
+	Groups []string `json:"groups"`
 }
 
 // Connector is an object that contains the metadata about connectors used to login to Dex.
